﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.IO;

namespace snat.util {
    public class DataChart : INotifyPropertyChanged {

        private Dictionary<string, DataSeries> seriesList;
        public Dictionary<string, DataSeries> SeriesList {
            get { return seriesList; }
            private set {
                seriesList = value;
                if (PropertyChanged != null) {
                    PropertyChanged.Invoke(this, new PropertyChangedEventArgs("SeriesList"));
                }
            }
        }

        private DataChartOptions options;
        public DataChartOptions Options {
            get { return options; }
            set {
                options = value;
                if (PropertyChanged != null) {
                    PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Options"));
                }
            }
        }

        // Construct with a single data series
        public DataChart(DataChartOptions options, DataSeries series) {
            this.options = options;
            seriesList = new Dictionary<string, DataSeries>();
            seriesList.Add(series.SeriesName, series);
        }

        // Construct with multiple 'stacked' data series
        public DataChart(DataChartOptions options, List<DataSeries> listOfSeries) {
            this.options = options;
            this.seriesList = new Dictionary<string, DataSeries>();

            foreach (DataSeries s in listOfSeries) {
                this.seriesList.Add(s.SeriesName, s);
            }
        }

        // Add a new series to the chart
        public bool AddSeries(DataSeries s) {
            SeriesList.Add(s.SeriesName, s);
            if (SeriesList.ContainsKey(s.SeriesName) && SeriesList.ContainsValue(s)) return true;
            return false;
        }

        // Remove a series from the chart
        public bool RemoveSeries(string seriesName) {
            return SeriesList.Remove(seriesName);
        }

        // Clear the data series list
        public void EmptyChart() {
            SeriesList.Clear();
        }

        // Return the name of the series at the given index in SeriesList
        public string SeriesNameAt(int index) {
            return SeriesList.ElementAt(index).Key;
        }

        // Returns the first series
        public DataSeries GetFirstSeries() {
            return SeriesList.ElementAt(0).Value;
        }

        // Save out chart as CSV
        public void ConvertToCSV(string filename) {
            using (StreamWriter output = new StreamWriter(filename)) {

                output.WriteLine(this.Options.Title);
                output.WriteLine(this.Options.Description);
                output.WriteLine();

                foreach (DataSeries series in this.SeriesList.Values) {
                    if (series.Series.Count > 0) {
                        output.WriteLine(series.SeriesName);

                        StringBuilder xvals = new StringBuilder();
                        StringBuilder yvals = new StringBuilder();

                        for(int i=0; i<series.Series.Count; i++) {
                            xvals.Append(series.Series[i].IndependentValue.ToString());
                            yvals.Append(series.Series[i].DependentValue.ToString());
                            if (i != series.Series.Count-2) {
                                xvals.Append(",");
                                yvals.Append(",");
                            }
                        }                   

                        output.WriteLine(xvals);
                        output.WriteLine(yvals);
                        output.WriteLine();
                    }
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}
